package com.example.testplatform.controller;

import com.example.testplatform.common.LogUtils;
import com.example.testplatform.common.Result;
import com.example.testplatform.service.RoleMenuService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 角色菜单管理控制器
 * 处理角色和菜单的关联关系，提供权限分配功能
 */
@RestController
@RequestMapping("/api/system/role-menus")
public class RoleMenuController {
    
    private static final Logger logger = LogUtils.getLogger(RoleMenuController.class);
    
    @Autowired
    private RoleMenuService roleMenuService;
    
    /**
     * 根据角色ID获取菜单ID列表
     * @param roleId 角色ID
     * @return 菜单ID列表
     */
    @GetMapping("/{roleId}")
    public Result<List<Long>> getMenuIdsByRoleId(@PathVariable Long roleId) {
        long startTime = System.currentTimeMillis();
        LogUtils.logBusiness(logger, "ROLE_MENU_QUERY_ATTEMPT", "system", "尝试根据角色ID获取菜单权限");
        LogUtils.logApiRequest(logger, "GET", "/api/system/role-menus/" + roleId, null);
        LogUtils.debug(logger, () -> "开始处理根据角色ID获取菜单权限请求，角色ID=" + roleId);
        
        try {
            // 验证参数
            if (roleId == null || roleId <= 0) {
                LogUtils.warn(logger, "根据角色ID获取菜单权限失败: 角色ID必须大于0，当前值=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_QUERY_FAILED", "system", "根据角色ID获取菜单权限失败: 角色ID无效");
                return Result.fail("角色ID无效");
            }
            
            LogUtils.info(logger, () -> "执行根据角色ID获取菜单权限操作，角色ID=" + roleId);
            List<Long> menuIds = roleMenuService.getMenuIdsByRoleId(roleId);
            
            LogUtils.debug(logger, () -> "根据角色ID获取菜单权限成功，角色ID=" + roleId + "，获取到" + menuIds.size() + "个菜单ID");
            LogUtils.logBusiness(logger, "ROLE_MENU_QUERY_SUCCESS", "system", "根据角色ID获取菜单权限成功，角色ID=" + roleId);
            LogUtils.logPerformance(logger, "getMenuIdsByRoleId", startTime, System.currentTimeMillis());
            
            LogUtils.info(logger, () -> "根据角色ID获取菜单权限请求处理完成，耗时=" + (System.currentTimeMillis() - startTime) + "ms");
            return Result.success(menuIds);
        } catch (Exception e) {
            LogUtils.logApiError(logger, "GET", "/api/system/role-menus/" + roleId, e);
            LogUtils.error(logger, "获取角色菜单权限过程发生异常: " + LogUtils.formatException(e));
            LogUtils.logBusiness(logger, "ROLE_MENU_QUERY_FAILED", "system", "获取角色菜单权限失败: " + e.getMessage());
            LogUtils.logPerformance(logger, "getMenuIdsByRoleId", startTime, System.currentTimeMillis());
            return Result.fail("获取角色菜单权限失败: " + e.getMessage());
        }
    }
    
    /**
     * 为角色分配菜单权限
     * @param roleId 角色ID
     * @param menuIds 菜单ID列表
     * @return 分配结果
     */
    @PostMapping("/{roleId}")
    public Result<String> assignMenusToRole(@PathVariable Long roleId, @RequestBody List<Long> menuIds) {
        long startTime = System.currentTimeMillis();
        LogUtils.logBusiness(logger, "ROLE_MENU_ASSIGN_ATTEMPT", "system", "尝试为角色分配菜单权限");
        LogUtils.logApiRequest(logger, "POST", "/api/system/role-menus/" + roleId, menuIds != null ? menuIds.toString() : "空请求");
        LogUtils.debug(logger, () -> "开始处理为角色分配菜单权限请求，角色ID=" + roleId);
        
        try {
            // 验证参数
            if (roleId == null || roleId <= 0) {
                LogUtils.warn(logger, "为角色分配菜单权限失败: 角色ID必须大于0，当前值=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_ASSIGN_FAILED", "system", "为角色分配菜单权限失败: 角色ID无效");
                return Result.fail("角色ID无效");
            }
            
            if (menuIds == null || menuIds.isEmpty()) {
                LogUtils.warn(logger, "为角色分配菜单权限失败: 菜单ID列表不能为空，角色ID=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_ASSIGN_FAILED", "system", "为角色分配菜单权限失败: 菜单ID列表不能为空");
                return Result.fail("菜单ID列表不能为空");
            }
            
            LogUtils.debug(logger, () -> "获取分配菜单权限请求参数: 角色ID=" + roleId + "，菜单ID数量=" + menuIds.size());
            
            LogUtils.info(logger, () -> "执行分配菜单权限操作，角色ID=" + roleId + "，菜单ID数量=" + menuIds.size());
            boolean success = roleMenuService.assignMenusToRole(roleId, menuIds);
            
            if (success) {
                LogUtils.debug(logger, () -> "为角色分配菜单权限成功，角色ID=" + roleId + "，共分配" + menuIds.size() + "个菜单权限");
                LogUtils.logBusiness(logger, "ROLE_MENU_ASSIGN_SUCCESS", "system", "为角色分配菜单权限成功，角色ID=" + roleId);
                LogUtils.logPerformance(logger, "assignMenusToRole", startTime, System.currentTimeMillis());
                
                LogUtils.info(logger, () -> "为角色分配菜单权限请求处理完成，耗时=" + (System.currentTimeMillis() - startTime) + "ms");
                return Result.success("权限分配成功");
            } else {
                LogUtils.warn(logger, "为角色分配菜单权限失败: 未知原因，角色ID=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_ASSIGN_FAILED", "system", "为角色分配菜单权限失败: 未知原因");
                return Result.fail("权限分配失败");
            }
        } catch (Exception e) {
            LogUtils.logApiError(logger, "POST", "/api/system/role-menus/" + roleId, e);
            LogUtils.error(logger, "分配权限过程发生异常: " + LogUtils.formatException(e));
            LogUtils.logBusiness(logger, "ROLE_MENU_ASSIGN_FAILED", "system", "权限分配失败: " + e.getMessage());
            LogUtils.logPerformance(logger, "assignMenusToRole", startTime, System.currentTimeMillis());
            return Result.fail("权限分配失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除角色的所有菜单权限
     * @param roleId 角色ID
     * @return 删除结果
     */
    @DeleteMapping("/{roleId}")
    public Result<String> removeAllMenusFromRole(@PathVariable Long roleId) {
        long startTime = System.currentTimeMillis();
        LogUtils.logBusiness(logger, "ROLE_MENU_REMOVE_ATTEMPT", "system", "尝试删除角色的所有菜单权限");
        LogUtils.logApiRequest(logger, "DELETE", "/api/system/role-menus/" + roleId, null);
        LogUtils.debug(logger, () -> "开始处理删除角色的所有菜单权限请求，角色ID=" + roleId);
        
        try {
            // 验证参数
            if (roleId == null || roleId <= 0) {
                LogUtils.warn(logger, "删除角色的所有菜单权限失败: 角色ID必须大于0，当前值=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_REMOVE_FAILED", "system", "删除角色的所有菜单权限失败: 角色ID无效");
                return Result.fail("角色ID无效");
            }
            
            LogUtils.info(logger, () -> "执行删除角色的所有菜单权限操作，角色ID=" + roleId);
            boolean success = roleMenuService.removeAllMenusFromRole(roleId);
            
            if (success) {
                LogUtils.debug(logger, () -> "删除角色的所有菜单权限成功，角色ID=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_REMOVE_SUCCESS", "system", "删除角色的所有菜单权限成功，角色ID=" + roleId);
                LogUtils.logPerformance(logger, "removeAllMenusFromRole", startTime, System.currentTimeMillis());
                
                LogUtils.info(logger, () -> "删除角色的所有菜单权限请求处理完成，耗时=" + (System.currentTimeMillis() - startTime) + "ms");
                return Result.success("删除角色权限成功");
            } else {
                LogUtils.warn(logger, "删除角色的所有菜单权限失败: 未知原因，角色ID=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_REMOVE_FAILED", "system", "删除角色的所有菜单权限失败: 未知原因");
                return Result.fail("删除角色权限失败");
            }
        } catch (Exception e) {
            LogUtils.logApiError(logger, "DELETE", "/api/system/role-menus/" + roleId, e);
            LogUtils.error(logger, "删除角色权限过程发生异常: " + LogUtils.formatException(e));
            LogUtils.logBusiness(logger, "ROLE_MENU_REMOVE_FAILED", "system", "删除角色权限失败: " + e.getMessage());
            LogUtils.logPerformance(logger, "removeAllMenusFromRole", startTime, System.currentTimeMillis());
            return Result.fail("删除角色权限失败: " + e.getMessage());
        }
    }
    
    /**
     * 检查角色是否有权限访问指定菜单
     * @param roleId 角色ID
     * @param menuId 菜单ID
     * @return 检查结果
     */
    @GetMapping("/check-permission")
    public Result<Boolean> checkPermission(
            @RequestParam Long roleId,
            @RequestParam Long menuId) {
        long startTime = System.currentTimeMillis();
        LogUtils.logBusiness(logger, "ROLE_MENU_PERMISSION_CHECK_ATTEMPT", "system", "尝试检查角色是否有权限访问指定菜单");
        LogUtils.logApiRequest(logger, "GET", "/api/system/role-menus/check-permission", "roleId=" + roleId + ", menuId=" + menuId);
        LogUtils.debug(logger, () -> "开始处理检查角色权限请求，角色ID=" + roleId + "，菜单ID=" + menuId);
        
        try {
            // 验证参数
            if (roleId == null || roleId <= 0) {
                LogUtils.warn(logger, "检查角色权限失败: 角色ID必须大于0，当前值=" + roleId);
                LogUtils.logBusiness(logger, "ROLE_MENU_PERMISSION_CHECK_FAILED", "system", "检查角色权限失败: 角色ID无效");
                return Result.fail("角色ID无效");
            }
            
            if (menuId == null || menuId <= 0) {
                LogUtils.warn(logger, "检查角色权限失败: 菜单ID必须大于0，当前值=" + menuId);
                LogUtils.logBusiness(logger, "ROLE_MENU_PERMISSION_CHECK_FAILED", "system", "检查角色权限失败: 菜单ID无效");
                return Result.fail("菜单ID无效");
            }
            
            LogUtils.info(logger, () -> "执行检查角色权限操作，角色ID=" + roleId + "，菜单ID=" + menuId);
            boolean hasPermission = roleMenuService.checkPermission(roleId, menuId);
            
            LogUtils.debug(logger, () -> "检查角色权限成功，角色ID=" + roleId + "，菜单ID=" + menuId + "，结果=" + hasPermission);
            LogUtils.logBusiness(logger, "ROLE_MENU_PERMISSION_CHECK_SUCCESS", "system", "检查角色权限成功，角色ID=" + roleId + "，菜单ID=" + menuId + "，结果=" + hasPermission);
            LogUtils.logPerformance(logger, "checkPermission", startTime, System.currentTimeMillis());
            
            LogUtils.info(logger, () -> "检查角色权限请求处理完成，耗时=" + (System.currentTimeMillis() - startTime) + "ms");
            return Result.success(hasPermission);
        } catch (Exception e) {
            LogUtils.logApiError(logger, "GET", "/api/system/role-menus/check-permission", e);
            LogUtils.error(logger, "权限检查过程发生异常: " + LogUtils.formatException(e));
            LogUtils.logBusiness(logger, "ROLE_MENU_PERMISSION_CHECK_FAILED", "system", "权限检查失败: " + e.getMessage());
            LogUtils.logPerformance(logger, "checkPermission", startTime, System.currentTimeMillis());
            return Result.fail("权限检查失败: " + e.getMessage());
        }
    }
}